1 /***
2 * Redistribution and use of this software and associated documentation
3 * ("Software"), with or without modification, are permitted provided
4 * that the following conditions are met:
5 *
6 * 1. Redistributions of source code must retain copyright
7 * statements and notices. Redistributions must also contain a
8 * copy of this document.
9 *
10 * 2. Redistributions in binary form must reproduce the
11 * above copyright notice, this list of conditions and the
12 * following disclaimer in the documentation and/or other
13 * materials provided with the distribution.
14 *
15 * 3. The name "Exolab" must not be used to endorse or promote
16 * products derived from this Software without prior written
17 * permission of Exoffice Technologies. For written permission,
18 * please contact info@exolab.org.
19 *
20 * 4. Products derived from this Software may not be called "Exolab"
21 * nor may "Exolab" appear in their names without prior written
22 * permission of Exoffice Technologies. Exolab is a registered
23 * trademark of Exoffice Technologies.
24 *
25 * 5. Due credit should be given to the Exolab Project
26 * (http://www.exolab.org/).
27 *
28 * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS
29 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
32 * EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39 * OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * Copyright 2000-2001,2003 (C) Exoffice Technologies Inc. All Rights Reserved.
42 */
43
44 package org.exolab.jms.selector;
45
46 import javax.jms.Message;
47
48 import org.apache.oro.text.regex.Pattern;
49 import org.apache.oro.text.regex.PatternMatcher;
50 import org.apache.oro.text.regex.Perl5Matcher;
51
52
53 /***
54 * This class implements a 'like' expression.
55 * This is an expression that returns true if a identifier's value matches
56 * a pattern
57 *
58 * @version $Revision: 1.1 $ $Date: 2004/11/26 01:50:44 $
59 * @author <a href="mailto:tma@netspace.net.au">Tim Anderson</a>
60 * @see Identifier
61 * @see IdentifierExpression
62 * @see RegexpFactory
63 */
64 class LikeExpression extends IdentifierExpression {
65
66 /***
67 * The regular expression
68 */
69 private final Pattern _regexp;
70
71 /***
72 * The pattern matcher
73 */
74 private final PatternMatcher _matcher;
75
76 /***
77 * The pattern
78 */
79 private final String _pattern;
80
81 /***
82 * The escape character. May be null.
83 */
84 private final String _escape;
85
86
87 /***
88 * Construct a new <code>LikeExpression</code>
89 *
90 * @param identifier the identifier
91 * @param pattern the pattern
92 * @param escape the escape character. May be null.
93 * @throws SelectorException if <code>pattern</code> or <code>escape</code>
94 * are invalid
95 */
96 public LikeExpression(final Identifier identifier, final String pattern,
97 final String escape) throws SelectorException {
98 super(identifier);
99 _pattern = pattern;
100 _escape = escape;
101 _regexp = getRegexp(_pattern, _escape);
102 _matcher = new Perl5Matcher();
103 }
104
105 /***
106 * Evaluate the expression
107 *
108 * @param msg the message to use to obtain any header identifier and
109 * property values
110 * @return the evaluated result, or <code>null</code> if the value of the
111 * expression is unknown
112 * @throws TypeMismatchException if the expression tries to evaluate
113 * mismatched types.
114 */
115 public final SObject evaluate(final Message msg)
116 throws TypeMismatchException {
117 SBool result = null;
118 SString value = TypeCaster.castToString(identifier().evaluate(msg),
119 "like expression");
120 if (value != null) {
121 if (_matcher.matches((String) value.getObject(), _regexp)) {
122 result = SBool.TRUE;
123 } else {
124 result = SBool.FALSE;
125 }
126 }
127 return result;
128 }
129
130 /***
131 * Return a string representation of this expression.
132 *
133 * @return a string representation of this expression
134 */
135 public final String toString() {
136 StringBuffer result = new StringBuffer();
137 result.append('(');
138 result.append(identifier().toString());
139 result.append(" like '");
140 result.append(_pattern);
141 result.append('\'');
142 if (_escape != null) {
143 result.append(" escape '");
144 result.append(_escape);
145 result.append('\'');
146 }
147 result.append(')');
148 return result.toString();
149 }
150
151 /***
152 * Converts the pattern and escape to an ORO <code>Pattern</code>
153 *
154 * @param pattern the pattern
155 * @param escape the escape character. May be null
156 * @return an ORO <code>Pattern</code> corresponding to
157 * <code>pattern</code> and <code>escape</code>
158 * @throws SelectorException if <code>pattern</code> or <code>escape</code>
159 * are invalid
160 */
161 private Pattern getRegexp(final String pattern, final String escape)
162 throws SelectorException {
163 Pattern result = null;
164 Character esc = null;
165
166 if (escape != null) {
167 if (escape.length() != 1) {
168 throw new SelectorException("Invalid escape: " + escape);
169 }
170 esc = new Character(escape.charAt(0));
171 }
172
173 try {
174 result = RegexpFactory.create(pattern, esc);
175 } catch (InvalidRegexpException err) {
176 throw new SelectorException("Invalid pattern: " + pattern);
177 }
178 return result;
179 }
180
181 }